/*
 * pattern.h
 *
 *  Created on: Sep 26, 2013
 *      Author: killerg
 */

#ifndef PATTERN_H_
#define PATTERN_H_

#include <functional>
#include <map>
#include <list>
#include <set>
#include <vector>

template<typename T>
class Singleton {
protected:
    Singleton() {
    }
    virtual ~Singleton() {
    }

private:
    Singleton(const Singleton&);
    Singleton& operator=(const Singleton&);

public:
    static T& Instance() {
        static T theInstance;
        return theInstance;
    }
};

template<typename K, typename V, typename MapT = std::map<K, V> >
class ptr_map : public std::map<K, V> {
    public:
        V get(K key) {
            auto itr = this->find(key);
            if (this->end() == itr) {
                return V(NULL);
            }
            return itr->second;
        }

        void set(K key, V value) {
            (*this)[key] = value;
        }
        // 若回调中value被置为NULL 则移除之
        void for_each(std::function<void(K, V&)> cb) {
            for (auto itr = this->begin(); itr != this->end(); ) {
                auto cur_itr = itr++;
                cb(cur_itr->first, cur_itr->second);
                if (NULL == cur_itr->second)
                    this->erase(cur_itr);
            }
        }
        // 当cb true时进行下一个 所有都为true为true
        // 若回调中value被置为NULL 则移除之
        bool do_while(std::function<bool(K, V&)> cb) {
            for (auto itr = this->begin(); itr != this->end(); ) {
                auto cur_itr = itr++;
                if (!cb(cur_itr->first, cur_itr->second))
                    return false;
                if (NULL == cur_itr->second)
                    this->erase(cur_itr);
            }
            return true;
        }
          typename std::map<K, V>::iterator find(const typename std::map<K, V>::key_type& __x) {
              return std::map<K, V>::find(__x);
          }
//          typename std::map<K, V>::iterator begin()
//          { return std::map<K, V>::begin(); }


};

template<typename T>
void for_each(std::vector<T> &con, std::function<void(T&)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        cb(*itr);
    }
}

template<typename T>
void for_each(std::list<T> &con, std::function<void(T&)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        cb(*itr);
    }
}

template<typename T>
void for_each(std::set<T> &con, std::function<void(T)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        cb(*itr);
    }
}


template<typename T>
void until(std::vector<T> &con, std::function<bool(T&)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        if (!cb(*itr))
            break;
    }
}

template<typename T>
void until(std::list<T> &con, std::function<bool(T&)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        if (!cb(*itr))
            break;
    }
}

template<typename T>
void until(std::set<T> &con, std::function<bool(T)> cb) {
    for (auto itr = con.begin(); itr != con.end(); ++itr) {
        if (!cb(*itr))
            break;
    }
}


#endif /* PATTERN_H_ */
